#include "my_header.h"
#include "my_epoll.h"

char *pconf_file = NULL;

#define MY_CONF_FILE pconf_file



void read_conf( const char* p_file,
					const char* p_section,
					const char* p_keyword,
					char* p_result,
					int keyword_len)
{
	FILE* p_file_stream;
	unsigned char	buff[256],*p,*q;
	int 	i;
	char	*p_buf,section_flag='\0';
	int 	len=0;

	if ( !p_file || !p_section || !p_keyword || !p_result )
	{
		return;
	}

	if ( ! (p_file_stream=fopen(p_file, "rt") ) )
	{
		return;
	}

	for(;;)
	{
		if ( !fgets((char*)buff,255,p_file_stream) )
		{
			break;
		}

		p = buff;

		while ( *p==32 || *p==9 )
		{
			p++;
		}


		if ( !*p || *p=='#' || *p==';' ||
			( *p=='/' && *(p+1)=='/') || *p==13 || *p==10 )
		{
			continue;
		}

		if ( section_flag )
		{
			if ( *p == '[' )
			{
				break;
			}

			q=(unsigned char*)p_keyword;

			while ( (*p==*q) && (*p!='=') && *q )
			{
				p++;
				q++;
			}

			while ( *p==32 || *p==9 )
			{
				p++;
			}

			if ( ( *p!='=' ) || *q	)
			{
				continue;
			}

			p++;
			while ( *p==32 || *p==9 )
			{
				p++;
			}

			p_buf = p_result;
			i = 0;
			while ( !( !*p || *p=='#' || *p==';' || *p==9 ||
					  ( *p=='/' && *(p+1)=='/') || *p==13 || *p==10 ))
			{
				if ( *p==32 )
				{
					i++;
				}
				else
				{
					while ( i )
					{
						i--;
						len++;
						if(len>keyword_len)
						{
							fclose( p_file_stream );
							return;
						}
						*p_buf++ = 32;
					}
					len++;
					if(len>keyword_len)
					{
						fclose( p_file_stream );
						return;
					}
					*p_buf++ = *p;
				}
				p++;
			}
			len++;
			if(len>keyword_len)
			{
				fclose( p_file_stream );
				return ;
			}
			*p_buf = '\0';
			fclose( p_file_stream );
			return	;
		}
		else
		{
			if ( *p != '[' )
			{
				continue;
			}

			p++;
			while ( *p==32 || *p==9 )
			{
				p++;
			}

			q=(unsigned char*)p_section;

			while ( (*p==*q) && (*p!=']') && *q )
			{
				p++;
				q++;
			}
			while ( *p==32 || *p==9 )
			{
				p++;
			}

			if ( ( *p==']' ) && !*q  )
			{
				section_flag='9';
			}
		}
	}

	fclose( p_file_stream );
	return;
}



int read_keyword(FILE* p_file_stream,
					const char* p_keyword,
					char* p_result,
					int keyword_len,
					int result_len)
{
	unsigned char	buff[256],*p,*q;
	int 	i = 0, r_len = 0;

	if ( !p_file_stream || !p_keyword || !p_result )
	{
		return -3;
	}

	for(;;)
	{
		if (!fgets((char*)buff,255,p_file_stream) )	//
		{
			return 0;//
		}

		i = strlen((const char*)buff);
		r_len += i;

		p = buff;

		while ( *p==32 || *p==9 )		  //
		{
			p++;
		}


		if ( !*p || *p=='#' || *p==';' ||
			( *p=='/' && *(p+1)=='/') || *p==13 || *p==10 )
		{
			continue;
		}

		if ( *p == '[' )
		{
			fseek(p_file_stream, -i, SEEK_CUR);
			return 1;		//
		}

		q=(unsigned char*)p_keyword;

		while (*p != '\0' && *p != '=' && --keyword_len > 0)
		{
			*q = *p;
			q ++;
			p ++;
		}

		if (( *p=='\0' ) || keyword_len <= 0  )
		{
			return -4;
		}

		q --;
		while ( *q==32 || *q==9 )		  //
		{
			q--;
		}
		q ++;
		*q = '\0';

		p++;
		q=(unsigned char*)p_result;

		while ( *p==32 || *p==9 )		  //
		{
			p++;
		}

		while (*p != '\0' && *p != '\r' && *p != '\n' && --result_len > 0)
		{
			*q = *p;
			q ++;
			p ++;
		}

		if (( *p=='\0' ) || result_len <= 0  )
		{
			return -5;
		}

		q --;
		while ( *q==32 || *q==9 )		  //
		{
			q--;
		}
		q ++;
		*q = '\0';

		return	r_len;
	}

	return 0;
}


int read_section( FILE* p_file_stream,
					char* p_section,
					int p_section_len)
{
	unsigned char	buff[256],*p,*q;
	int  r_len = 0;


	if (!p_file_stream || !p_section)
	{
		fprintf(stderr, "%s", "parameter error!\n");
		return -2;
	}

	while(1)
	{
		if(!fgets((char*)buff,255,p_file_stream))//
		{
			fprintf(stderr, "%s", "fgets file error!\n");
			return 0;//
		}

		r_len += strlen((const char*)buff);
		p = buff;

		while ( *p==32 || *p==9 )		  //
		{
			p++;
		}


		if ( !*p || *p=='#' || *p==';' ||
			( *p=='/' && *(p+1)=='/') || *p==13 || *p==10 )
		{
			continue;
		}

		if ( *p != '[' )
		{
			continue;
		}

		p++;

		while ( *p==32 || *p==9 )		//
		{
			p++;
		}

		q=(unsigned char*)p_section;

		while (*p!=']' && *p != '\0' && --p_section_len > 0)
		{
			*q = *p;
			q ++;
			p ++;
		}

		if ( ( *p==']' ) && p_section_len >= 0  )//
		{
			q --;
			while ( *q==32 || *q==9 )		  //
			{
				q--;
			}
			q ++;
			*q = '\0';

			return r_len;
		}
		else
		{
			fprintf(stderr, "%s", "get section error!\n");
			fseek(p_file_stream, -r_len, SEEK_CUR);
			return -3;
		}
	}

	return 0;
}



int init_share_lib(epoll_sock_t *p_epoll, char *conf_file, base_func_t *pfunc)
{
	char path_name[256] = {};
	char func_init[64] = {};
	char func_exit[64] = {};
	char func_start[64] = {};
	char func_end[64] = {};
	char func_read[64] = {};
	char func_write[64] = {};
	char *pfile = (char *)pfunc->pfile;

	FUNC_START("\n");
	MY_CONF_FILE = conf_file;
	//
	read_conf(MY_CONF_FILE,
				"plugin_process",
				"path+name",
				path_name, sizeof(path_name) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_init",
				func_init, sizeof(func_init) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_exit",
				func_exit, sizeof(func_exit) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_start",
				func_start, sizeof(func_start) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_end",
				func_end, sizeof(func_end) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_read",
				func_read, sizeof(func_read) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"func_write",
				func_write, sizeof(func_write) - 1);

	read_conf(MY_CONF_FILE,
				"plugin_process",
				"datafile",
				pfile, sizeof(pfunc->pfile) - 1);

	p_epoll->p_lib = dlopen((char *)path_name, RTLD_NOW | RTLD_GLOBAL);

	if(p_epoll->p_lib == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to load the library!\n");
		char *p_err = dlerror();
		if(p_err != NULL)
		{
			DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		}
		FUNC_RETURN(MY_LOAD_DLL_ERROR);
	}

	/////////////////////////////////////////
	p_epoll->start_handler =
		dlsym(p_epoll->p_lib, func_start);
	if(p_epoll->start_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	p_epoll->end_handler =
		dlsym(p_epoll->p_lib, func_end);
	if(p_epoll->end_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	p_epoll->init_handler =
		dlsym(p_epoll->p_lib, func_init);
	if(p_epoll->init_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	p_epoll->exit_handler =
		dlsym(p_epoll->p_lib, func_exit);
	if(p_epoll->exit_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	p_epoll->read_handler =
		dlsym(p_epoll->p_lib, func_read);
	if(p_epoll->read_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	p_epoll->write_handler =
		dlsym(p_epoll->p_lib, func_write);
	if(p_epoll->write_handler == NULL)
	{
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"Fail to get the parse_client_pop3\
				    fuction address!\n");
		char *p_err = dlerror();
		DEBUG_EPOLL(EPOLL_DBG_FUNC, EPOLL_ERROR,"%s\n", p_err);
		FUNC_RETURN(MY_LOAD_FUNC_ERROR);
	}

	FUNC_RETURN( MY_NO_ERROR);
}

int exit_share_lib(epoll_sock_t *p_epoll)
{
	FUNC_START("\n");

	if(p_epoll->p_lib)
	{
		dlclose(p_epoll->p_lib);
	}

	FUNC_RETURN( MY_NO_ERROR);
}

